home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / sharew / accs / drupatch / rich_lib / ldiv.c < prev   
Encoding:
Text File  |  1985-07-21  |  2.4 KB  |  125 lines

  1. /*
  2.  *        _ldiv  -  Division  u / v
  3.  *
  4.  *        Bestimme q und r mit  u = q * v + r  und  0 <= |r| < |v|.
  5. */
  6.  
  7. long _ldiv (v,u)
  8. long  u,v;
  9. {
  10.     asm {
  11.                 movem.l    D4-D7,-(A7)
  12.                 clr        D7                    ; kennzeichnet das Vorzeichen
  13.                 clr.l    D0                    ; Quotient q
  14.                 move.l    u(A6),D5            ; u := (u1,u2)
  15.                 move.l    v(A6),D3            ; v := (v1,v2)
  16.                 bne        v_ok
  17.                 divs    D3,D5                ; Division durch 0
  18.                 bra        ret
  19.         v_ok:
  20.                 bge        v_ge
  21.                 neg.l    D3
  22.                 addq    #1,D7                ; negativer Quotient
  23.         v_ge:
  24.                 tst.l    D5
  25.                 bge        u_ge
  26.                 neg.l    D5
  27.                 addq    #3,D7                ; negativer Dividend
  28.         u_ge:
  29.                 cmp.l    D5,D3
  30.                 bgt        ready                ; v > u ?
  31.                 bne        not_eq                ; v != u ?
  32.                 move.l    #1,D0                ; q = 1
  33.                 clr.l    D5                    ; r = 0
  34.                 bra        ready
  35.         not_eq:
  36.                 move.l    D3,D4
  37.                 swap    D4
  38.                 tst        D4
  39.                 beq        v_word                ; v < 2**16 ?
  40.  
  41.                 moveq    #15,D2                ; bestimme Normierungsfaktor
  42.                 move    #0xFF00,D1
  43.                 and        D4,D1
  44.                 beq        len_8
  45.                 lsr        #8,D4
  46.                 subq    #8,D2
  47.         len_8:    moveq    #0xF0,D1
  48.                 and.b    D4,D1
  49.                 beq        len_4
  50.                 lsr        #4,D4
  51.                 subq    #4,D2
  52.         len_4:    moveq    #0xC,D1
  53.                 and.b    D4,D1
  54.                 beq        len_2
  55.                 lsr        #2,D4
  56.                 subq    #2,D2
  57.         len_2:    moveq    #0x2,D1
  58.                 and.b    D4,D1
  59.                 beq        len_1
  60.                 subq    #1,D2
  61.         len_1:
  62.                 asl.l    D2,D3                ; normalisiere v
  63.                 clr.l    D4
  64.                 move    D3,D4                ; D4 = v2
  65.                 clr        D3
  66.                 swap    D3                    ; D3 = v1
  67.  
  68.                 move.l    D5,D6                ; normalisiere u
  69.                 clr        D5
  70.                 swap    D5
  71.                 asl.l    D2,D5
  72.                 asl.l    D2,D6                ; D6 = (u1,u2)
  73.                 move.l    D6,D1
  74.                 swap    D1
  75.                 move    D1,D5                ; D5 = (u0,u1)
  76.  
  77.                 divu    D3,D5                ; (u0,u1) / v1
  78.                 move    D5,D0                ; Quotient q
  79.                 move    D6,D5                ; r * 2**16 + u2
  80.                 move    D4,D1                ; v2
  81.                 mulu    D0,D1                ; v2 * q
  82.         q_test:
  83.                 cmp.l    D1,D5
  84.                 bcc        q_ok                ; D5 >= D1 ? (32 Bit)
  85.                 subq    #1,D0                ; q--
  86.                 sub.l    D4,D1                ; unsigned
  87.                 add.l    D3,D5                ; unsigned
  88.                 bcc        q_test
  89.         q_ok:
  90.                 sub.l    D1,D5                ; Rest r
  91.                 lsr.l    D2,D5
  92.                 bra        ready
  93.  
  94.         v_word:                                ; Divisor hat nur 2 Byte
  95.                 move.l    D5,D6
  96.                 clr        D6
  97.                 swap    D6                    ; D6 = u1
  98.                 cmp        D3,D6
  99.                 blt        low_div
  100.                 divu    D3,D6
  101.                 move    D6,D0                ; Quotient : High-Word
  102.                 swap    D0
  103.                 move    D5,D6
  104.                 move.l    D6,D5
  105.         low_div:
  106.                 divu    D3,D5
  107.                 move     D5,D0                ; Quotient : Low-Word
  108.                 clr        D5
  109.                 swap    D5                    ; Rest
  110.  
  111.         ready:
  112.                 cmp        #3,D7
  113.                 blt        r_pos
  114.                 neg.l    D5                    ; negiere Rest
  115.         r_pos:
  116.                 lsr        #1,D7
  117.                 bcc        q_pos
  118.                 neg.l    D0                    ; negiere Quotient
  119.         q_pos:
  120.                 move.l    D0,v(A6)
  121.                 move.l    D5,u(A6)
  122.         ret:
  123.                 movem.l    (A7)+,D4-D7
  124.     }
  125. }